背景
浏览器的 devtools 中资源的加载来源有 from memory 和 from disk 等等,这些资源加载的缓存底层是如何实现的呢?
——WebKit 自带的 HTTP 资源磁盘缓存机制
网页中依赖的资源有很多,通常包括 HTML/JS/CSS/图片/SVG/视频等文件,这些类型的文件在 Webkit 内部都有不同的类来表示
每一个资源类代表着一种文件类型,所有的资源类都有一个公共的基类 CachedResource。其中,HTML 属于 MainResource 类,与之对应的是 CachedRawResource 类
缓存池
缓存机制的思想就是通过建立一个缓存池,当 Webkit 需要资源的时候,默认去缓存池中寻找
靠什么寻找?靠的是 URL 来寻找,正好符合了 URL 统一资源定位符的气质
如果匹配则使用,如果不匹配则创建 CachedResource 下的一个对象,例如图片则创建 CachedIamge 对象,并通过网络模块获取
上面说到了 Webkit 中的资源,那怎么加载资源,肯定得有相应的加载器
加载器
通俗来讲,加载器 就是一个工具,从缓存池或者其他地方中取资源
Webkit 主要有三种加载器
- 特定的加载器,比如加载 image 就有特定的图片加载器,加载 js 就有特定的 js 加载器,加载字体就要特定的字体加载器
- 缓存机制的资源加载器,就是第一种特定加载器先来缓存机制的资源加载器中寻找缓存资源
- 通用的资源加载器,是在 Webkit 需要从网络或者文件系统获取资源时的加载器
第三种加载器,它是从网络或者文件系统获取资源,那么我们想说的 200fromdisk 也就是在此发生。
即 fromdisk 发生在 frommemory 之后。为什么我们说 fromdisk 是通过网络模块获取呢?因为在 Webkit 中,网络模块包含磁盘缓存
from memory 和 from disk
from memory,字面意思就是来自内存,其实这里表达的也就是字面的意思。指的是我们当前加载的这个资源是从内存中获取的
特点:这种请求不走浏览器,关闭页面时,内存会释放,再次打开也不会出现 frommemory。from disk,也是字面意思,就是资源来自磁盘
特点:来自磁盘中的数据肯定是我们之前缓存过得,它不会随着浏览器的关闭而消失,我们往往打开浏览器时会出现的就是 fromdisk(其中强制缓存和协商缓存就是这部分的使用场景
资源加载顺序就是:from memory=>from disk=>http request
缓存池策略
为什么我们刷新页面的时候在 network 有些是 from memory 有些是 from disk 而有些是重新加载呢
Webkit 中的缓存池肯定是有生命周期的,不可能让缓存池一直变大,否则就会内存溢出。因此,必须有相应的机制来控制缓存池的大小。
限制
Webkit 采用的是 LRU 算法即最近最少使用算法。该算法是内存管理常见的页面置换算法,它选择最近最久未使用的页面予以淘汰,以此来保障资源池的大小,这里是指内存缓存的资源池
硬盘缓存中,Webkit 会维护一个缓存资源表,该表中的关键字就是 URL。根据浏览器的情况来更新这个缓存表。同时,Webkit 也使用 LRU 算法来控制这张表的大小